﻿using System.IO;
using System.Threading.Tasks;
using CkSoftware.GroupMe.Sdk.Core;
using CkSoftware.GroupMe.Sdk.Core.Dao;
using CkSoftware.GroupMe.Sdk.Images.Commands;
using CkSoftware.GroupMe.Sdk.Images.Dao;

namespace CkSoftware.GroupMe.Sdk.Images
{
	/// <summary>
	/// Managing class for GroupMe images.
	/// </summary>
	public class GroupMeImages
	{
		private readonly IWebApiAccess _webApiAccess;

		/// <summary>
		/// Instantiate a new <see cref="GroupMeImages" /> object.
		/// </summary>
		/// <param name="webApiAccess">The <see cref="IWebApiAccess" /> to use for API calls.</param>
		public GroupMeImages(IWebApiAccess webApiAccess)
		{
			_webApiAccess = webApiAccess;
			_webApiAccess.AccessTokenParameter = "access_token";
		}

		/// <summary>
		/// Creates a new picture using the given web url and the given filename. Downloads the web-url content first and uploads it then to the GroupMe ImagingService.
		/// </summary>
		/// <param name="pictureUrl">The web URL of the image to upload.</param>
		/// <param name="fileName">The filename of the image.</param>
		/// <returns>The new created picture data which can be used in any avatar or message attachment.</returns>
		public PictureData CreatePicture(string pictureUrl, string fileName)
		{
			Task<PictureData> createPictureTask = CreatePictureFromUrl(pictureUrl, fileName);
			Task.WaitAll(createPictureTask);
			return createPictureTask.Result;
		}

		/// <summary>
		/// Creates a new picture using the given stream data and the given filename.
		/// </summary>
		/// <param name="data">The data stream containing the image.</param>
		/// <param name="fileName">The filename of the image.</param>
		/// <returns>The new created picture data which can be used in any avatar or message attachment.</returns>
		public PictureData CreatePicture(Stream data, string fileName)
		{
			Task<PictureData> createPictureTask = CreatePictureFromStream(data, fileName);
			Task.WaitAll(createPictureTask);
			return createPictureTask.Result;
		}

		/// <summary>
		/// Asynchronous creates a new picture using the given web url and the given filename. Downloads the web-url content first and uploads it then to the GroupMe ImagingService.
		/// </summary>
		/// <param name="pictureUrl">The web URL of the image to upload.</param>
		/// <param name="fileName">The filename of the image.</param>
		/// <returns>An awaitable Task resulting in the new created picture data which can be used in any avatar or message attachment.</returns>
		public async Task<PictureData> CreatePictureAsync(string pictureUrl, string fileName)
		{
			return await CreatePictureFromUrl(pictureUrl, fileName);
		}

		/// <summary>
		/// Asynchronous creates a new picture using the given stream data and the given filename asynchronous.
		/// </summary>
		/// <param name="data">The data stream containing the image.</param>
		/// <param name="fileName">The filename of the image.</param>
		/// <returns>An awaitable Task resulting in the new created picture data which can be used in any avatar or message attachment.</returns>
		public async Task<PictureData> CreatePictureAsync(Stream data, string fileName)
		{
			return await CreatePictureFromStream(data, fileName);
		}

		private async Task<PictureData> CreatePictureFromCommand(UploadPictureCommand command)
		{
			UploadPictureResponse result = await _webApiAccess.ExecuteCommand(command);

			return result.Picture;
		}

		private async Task<PictureData> CreatePictureFromStream(Stream data, string fileName)
		{
			return await CreatePictureFromCommand(new UploadPictureCommand(data, "file", fileName));
		}

		private async Task<PictureData> CreatePictureFromUrl(string pictureUrl, string fileName)
		{
			return await CreatePictureFromCommand(new UploadPictureCommand(pictureUrl, "file", fileName));
		}
	}
}